import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class CharCounter implements ICharCounter, IHuffConstants {
    private final int[] counts;
    
    /**
     * Constructor initializes the counter array
     */
    public CharCounter() {
        counts = new int[ALPH_SIZE];
        clear();
    }
    
    @Override
    public int getCount(int ch) {
        if (ch < 0 || ch >= ALPH_SIZE) {
            throw new IllegalArgumentException("Character value out of range: " + ch);
        }
        return counts[ch];
    }
    
    @Override
    public int countAll(InputStream stream) throws IOException {
        if (stream == null) {
            throw new IllegalArgumentException("Input stream cannot be null");
        }
        
        clear();
        int total = 0;
        int ch;
        
        while ((ch = stream.read()) != -1) {
            add(ch);
            total++;
        }
        
        return total;
    }
    
    @Override
    public void add(int i) {
        if (i < 0 || i >= ALPH_SIZE) {
            throw new IllegalArgumentException("Character value out of range: " + i);
        }
        counts[i]++;
    }
    
    @Override
    public void set(int i, int value) {
        if (i < 0 || i >= ALPH_SIZE) {
            throw new IllegalArgumentException("Character value out of range: " + i);
        }
        if (value < 0) {
            throw new IllegalArgumentException("Count cannot be negative: " + value);
        }
        counts[i] = value;
    }
    
    @Override
    public void clear() {
        Arrays.fill(counts, 0);
    }
    
    @Override
    public Map<Integer, Integer> getTable() {
        Map<Integer, Integer> table = new HashMap<>();
        for (int i = 0; i < counts.length; i++) {
            if (counts[i] > 0) {
                table.put(i, counts[i]);
            }
        }
        return table;
    }
}
